﻿using UnityEditor;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.U2D;
using UnityEditor.U2D;
using System.IO;

public class Editor {
    private EditorCoroutine EditorCoroutine = new EditorCoroutine();


    [MenuItem("Custom/InspectorFlipLocked &L")]
    public static void MenuItem_InspectorFlipLocked() {
        System.Type typeInspector = typeof(EditorWindow).Assembly.GetType("UnityEditor.InspectorWindow");
        EditorWindow w = EditorWindow.focusedWindow;
        if (!typeInspector.IsInstanceOfType(w)) {
            w = null;
            Object[] objs = Resources.FindObjectsOfTypeAll(typeInspector);
            if (objs.Length > 0) w = objs[0] as EditorWindow;
        }
        if (w != null) {
            //ActiveEditorTracker tracker = typeInspector.InvokeMember("GetTracker", BindingFlags.InvokeMethod, null, w, null) as ActiveEditorTracker;
            //也许是unity接口变了吧，GetTracker miss
            ActiveEditorTracker tracker = ActiveEditorTracker.sharedTracker;
            tracker.isLocked = !tracker.isLocked;
            Debug.Log("Inspector at " + w.position + " is " + (tracker.isLocked ? "LOCKED" : "UNLOCKED"));
            w.Repaint();
        }
    }

    public struct spriteAtlasBuild {
        public string spriteAtlasName;
        public string path;
    }

    [MenuItem("Custom/生成SpriteAtlas")]
    public static void MenuItem_BuildSpriteAtlas() {
        string spriteAtlasPath = "Assets/_ArtUsing/Atlas";

        List<spriteAtlasBuild> spriteAtlasBuilds = new List<spriteAtlasBuild>();


        string spriteAtlasFolderPath = "Assets/_ArtUsing/Image";
        List<string> spriteAtlasNames = new List<string>() {
            "Avatar",
            "Command",
            "Force",
            "Item",
            "ItemElement",
            "TaskImportantType",
            "Painting",
            "UIImage",
        };
        foreach (var spriteAtlasName in spriteAtlasNames) {
            spriteAtlasBuilds.Add(new spriteAtlasBuild { spriteAtlasName = spriteAtlasName, path = spriteAtlasFolderPath + "/" + spriteAtlasName });
        }

        //missileAnimation
        spriteAtlasBuilds.Add(new spriteAtlasBuild { spriteAtlasName = "bloodpriest_skill01_missile", path = "Assets/_ArtUsing/Image/MissileAnimation/bloodpriest/skill01/missile" });

        for (int i = 0; i < spriteAtlasBuilds.Count; i++) {
            if (File.Exists(spriteAtlasBuilds[i].path)) {
                File.Delete(spriteAtlasBuilds[i].path);
            }
            SpriteAtlas spriteAtlas = new SpriteAtlas();
            spriteAtlas.SetPackingSettings(new SpriteAtlasPackingSettings { padding = 8, enableTightPacking = false });
            spriteAtlas.SetPlatformSettings(new TextureImporterPlatformSettings { format = TextureImporterFormat.ARGB32 });
            spriteAtlas.SetTextureSettings(new SpriteAtlasTextureSettings { sRGB = true });
            List<Object> objects = new List<Object>();
            string[] files = Directory.GetFiles(spriteAtlasBuilds[i].path);
            foreach (var file in files) {
                if (!file.EndsWith(".meta"))
                    objects.Add(AssetDatabase.LoadAssetAtPath<Sprite>(file));
            }
            spriteAtlas.Add(objects.ToArray());

            AssetDatabase.CreateAsset(spriteAtlas, spriteAtlasPath + "/" + spriteAtlasBuilds[i].spriteAtlasName + ".spriteatlas");
            Debug.Log("生成spriteAtlas：" + spriteAtlasBuilds[i].spriteAtlasName);
        }

    }


    [MenuItem("Custom/生成AssetBundle")]
    public static void MenuItem_BuildAssetBundle() {
        //SpriteAtlas
        string[] spriteAtlasPaths = Directory.GetFiles("Assets/_ArtUsing/Atlas");
        List<string> spriteAtlasFiles = new List<string>();
        foreach (var str in spriteAtlasPaths) {
            if (!str.EndsWith(".mate")) spriteAtlasFiles.Add(str);
        }

        //获取characterPrefab路径
        List<string> characterPrefabs = new List<string>() { "ghostdomwarden" };
        List<string> characterPrefabPaths = new List<string>();
        foreach (var characterPrefab in characterPrefabs) {
            characterPrefabPaths.Add("Assets/_ArtUsing/Image/Character/" + characterPrefab + "/" + characterPrefab + ".prefab");
        }

        //获取mapGridPrefab路径
        List<string> mapGridPrefabs = new List<string>() { "battlemapgrid" };
        List<string> mapGridPrefabPaths = new List<string>();
        foreach (var mapGridPrefab in mapGridPrefabs) {
            mapGridPrefabPaths.Add("Assets/_Prefabs/" + mapGridPrefab + ".prefab");
        }

        List<AssetBundleBuild> builds = new List<AssetBundleBuild>() {
            new AssetBundleBuild {
                assetBundleName = "spriteAtlas.assetbundle",
                assetNames = spriteAtlasFiles.ToArray(),
            },
            new AssetBundleBuild {
                assetBundleName = "characterPrefab.assetbundle",
                assetNames = characterPrefabPaths.ToArray(),
            },
            new AssetBundleBuild {
                assetBundleName = "mapGridPrefab.assetbundle",
                assetNames = mapGridPrefabPaths.ToArray(),
            },

        };
        AssetBundleManifest assetBundleManifest = BuildPipeline.BuildAssetBundles(GlobalData.AssetBundlePath, builds.ToArray(), BuildAssetBundleOptions.None, BuildTarget.StandaloneWindows);
        Debug.Log("生成AssetBundles");
    }


    [MenuItem("Custom/SortingLayers/清除所有SortingLayers")]
    public static void MenuItemClearAllSortingLayers() {
        ClearSortingLayers();
    }

    [MenuItem("Custom/SortingLayers/显示所有SortingLayers")]
    public static void ReadSortingLayer() {
        SerializedObject tagManager = new SerializedObject(AssetDatabase.LoadAllAssetsAtPath("ProjectSettings/TagManager.asset")[0]);
        SerializedProperty it = tagManager.GetIterator();
        while (it.NextVisible(true)) {
            if (it.name == "m_SortingLayers") {
                var count = it.arraySize;
                for (int i = 0; i < count; i++) {
                    var dataPoint = it.GetArrayElementAtIndex(i);
                    while (dataPoint.NextVisible(true)) {
                        if (dataPoint.name == "name") {
                            Debug.Log(dataPoint.stringValue);
                            break;
                        }
                    }
                }


            }
        }
    }


    [MenuItem("Custom/SortingLayers/自动生成SortingLayers")]
    public static void MenuItem_BuildSortingLayers() {
        ClearSortingLayers();
        AddSortingLayer("Background", 1);
        Vector2Int size = GlobalData.sortingLayersSize;
        for (int i = 0; i < size.x * size.y; i++) {
            AddSortingLayer("Map" + i.ToString(), i + 1000);
        }
        AddSortingLayer("MissileAnimation", 2000);
    }

    private static void AddSortingLayer(string sortingLayer, int uniqueID) {
        if (!IsHasSortingLayer(sortingLayer)) {
            SerializedObject tagManager = new SerializedObject(AssetDatabase.LoadAllAssetsAtPath("ProjectSettings/TagManager.asset")[0]);
            SerializedProperty it = tagManager.GetIterator();
            while (it.NextVisible(true)) {
                if (it.name == "m_SortingLayers") {
                    Debug.Log("SortingLayers" + it.arraySize);
                    it.InsertArrayElementAtIndex(it.arraySize);
                    SerializedProperty dataPoint = it.GetArrayElementAtIndex(it.arraySize - 1);
                    while (dataPoint.NextVisible(true)) {
                        if (dataPoint.name == "name") {
                            dataPoint.stringValue = sortingLayer;
                        }

                        if (dataPoint.name == "uniqueID") {
                            dataPoint.intValue = uniqueID;
                            tagManager.ApplyModifiedProperties();
                            return;
                        }
                    }
                }
            }
        }

    }

    private static bool IsHasSortingLayer(string sortingLayer) {
        SerializedObject tagManager = new SerializedObject(AssetDatabase.LoadAllAssetsAtPath("ProjectSettings/TagManager.asset")[0]);
        SerializedProperty it = tagManager.GetIterator();
        while (it.NextVisible(true)) {
            if (it.name == "m_SortingLayers") {
                for (int i = 0; i < it.arraySize; i++) {
                    SerializedProperty dataPoint = it.GetArrayElementAtIndex(i);
                    while (dataPoint.NextVisible(true)) {
                        if (dataPoint.name == "name") {
                            if (dataPoint.stringValue == sortingLayer) return true;
                        }
                    }
                }
            }
        }

        return false;
    }

    private static void ClearSortingLayers() {
        SerializedObject tagManager = new SerializedObject(AssetDatabase.LoadAllAssetsAtPath("ProjectSettings/TagManager.asset")[0]);
        SerializedProperty it = tagManager.GetIterator();
        while (it.NextVisible(true)) {
            if (it.name == "m_SortingLayers") {
                it.ClearArray();
                tagManager.ApplyModifiedProperties();
                return;
            }
        }
    }


}

/// <summary>
/// UnityEditor下模拟协程
/// </summary>
public class EditorCoroutine {
    /// <summary>
    /// 迭代列表
    /// </summary>
    private static List<IEnumerator> _itors = null;

    /// <summary>
    /// 要从迭代列表中移除的索引
    /// </summary>
    private static List<int> _removeIdxs = null;

    private static EditorApplication.CallbackFunction _updateFunc = null;

    /// <summary>
    /// Update方法是否在执行
    /// </summary>
    private static bool _isUpdateRuning = false;

    static EditorCoroutine() {
        _itors = new List<IEnumerator>();
        _removeIdxs = new List<int>();
        _updateFunc = _Update;
    }

    public static void Start(IEnumerator itor) {
        _itors.Add(itor);
        _RunUpdate(true);
    }

    private static void _RunUpdate(bool isRun) {
        if (isRun == _isUpdateRuning) return;

        // 运行Update
        if (isRun) {
            EditorApplication.update += _updateFunc;
        }
        // 停止运行Update
        else {
            EditorApplication.update -= _updateFunc;
        }
        _isUpdateRuning = isRun;
    }

    private static void _Update() {
        if (null == _itors || _itors.Count <= 0) return;
        for (int i = 0, c = _itors.Count; i < c; ++i) {
            if (!_itors[i].MoveNext()) {
                _removeIdxs.Add(i);
            }
        }

        if (_removeIdxs.Count <= 0) return;
        for (int i = _removeIdxs.Count - 1; i >= 0; --i) {
            _itors.RemoveAt(_removeIdxs[i]);
            _removeIdxs.RemoveAt(i);
        }

        if (_itors.Count == 0) {
            _RunUpdate(false);
        }
    }
}